/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package org.ruslan.kolobok;

import java.util.HashMap;
import java.util.Map;

import org.ruslan.kolobok.model.FxType;
import org.ruslan.kolobok.model.Type;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.PixmapPacker;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ObjectMap;

public class Assets {
	public static Texture background;
	public static TextureRegion backgroundRegion;

	public static Texture items;
//	public static TextureRegion mainMenu;
	public static TextureRegion play;
	public static TextureRegion highScores;
	public static TextureRegion help;
	public static TextureRegion resume;
	public static TextureRegion quit;
	public static TextureRegion ready;
	public static TextureRegion gameOver;
	public static TextureRegion highScoresRegion;
	public static TextureRegion logo;
	public static TextureRegion soundOn;
	public static TextureRegion soundOff;
	public static TextureRegion arrow;
	public static TextureRegion pause;
	public static TextureRegion spring;
	public static TextureRegion castle;
	public static Animation coinAnim;
	public static Animation bobJump;
	public static Animation bobFall;
	public static TextureRegion bobHit;
	public static Animation squirrelFly;
	public static TextureRegion platform;
	public static Animation brakingPlatform;
	public static BitmapFont font;
	
	public static Texture crosshair;
//	public static TextureRegion soldier;
	public static TextureRegion dirt;
	public static TextureRegion hills;
	public static TextureRegion barrel;
	public static TextureRegion bullet_splash;
	public static TextureRegion hit;
	public static TextureRegion flash;
	public static TextureRegion up;
	public static TextureRegion down;

	public static Music music;
	public static Sound jumpSound;
	public static Sound highJumpSound;
	public static Sound hitSound;
	public static Sound coinSound;
	public static Sound clickSound;
	private static ObjectMap<String, ? extends Type> fxTypes;
	public static Type hitType;
	public static Type splashType;
	
	public static Map<String, TextureRegion> textureRegionsMap;
	
	private static final int BACKGROUND_WIDTH = 480;
	private static final int BACKGROUND_HEIGHT = 320;

	public static final String UI_FILE = "data/test.json";
//	public static final String UI_FILE = "data/uiskin60.json";
//	public static final String UI_SKIN = "data/uiskin60.png";

	public static Texture loadTexture (String file) {
		return new Texture(Gdx.files.internal(file));
	}
	
	private static <T extends Type> ObjectMap<String, T> readFile(FileHandle file, Class<T[]> arrayClass) {
		ObjectMap<String, T> map = new ObjectMap<String, T>();
		Json json = new Json();
		T[] entries = json.fromJson(arrayClass, file);
		for (T entry : entries) {
			map.put(entry.getName(), entry);
		}
		return map;
	}

	public static void load () {
		fxTypes = readFile(Gdx.files.internal("data/effects.json"), FxType[].class);
		hitType = fxTypes.get("hit");
		splashType = fxTypes.get("bullet_splash");
		
		background = loadTexture("data/background.png");
		backgroundRegion = new TextureRegion(background, 0, 0, BACKGROUND_HEIGHT, BACKGROUND_WIDTH);
		
		crosshair = loadTexture("data/crosshair.png");
//		Texture soldierTexture = loadTexture("data/soldier.png");
//		soldierTexture.setFilter(Texture.TextureFilter.Linear,
//				Texture.TextureFilter.Linear);
//		soldier = new TextureRegion(soldierTexture, 0, 0, 255, 255);
		
		
//		Texture dirtTexture = loadTexture("data/dirt.png");
		Texture dirtTexture = new Texture(Gdx.files.internal("data/dirt.png"));
		dirtTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
		dirtTexture.setFilter(Texture.TextureFilter.Nearest,
				Texture.TextureFilter.Nearest);
		dirt = new TextureRegion(dirtTexture, 0, 0, 255, 255);
		dirt.setV(0);
		dirt.setV2(40f);
		dirt.setU(0);
		dirt.setU2(40f);
		
		PixmapPacker packer = new PixmapPacker(1024, 256, Format.RGBA8888, 0, false);
		FileHandle file = Gdx.files.internal("data/hills.png");
		packer.pack("hills", new Pixmap(file));
		file = Gdx.files.internal("data/barrel.png");
		packer.pack("barrel", new Pixmap(file));
		packer.pack("bullet_splash", new Pixmap(Gdx.files.internal("data/bullet_splash.png")));
		packer.pack("hit", new Pixmap(Gdx.files.internal("data/hit.png")));
		packer.pack("flash", new Pixmap(Gdx.files.internal("data/flash.png")));
		packer.pack("btr", new Pixmap(Gdx.files.internal("data/btr.png")));
		packer.pack("up", new Pixmap(Gdx.files.internal("data/btn_default_normal.9.png")));
		packer.pack("down", new Pixmap(Gdx.files.internal("data/btn_default_pressed.9.png")));
		TextureAtlas atlas = packer.generateTextureAtlas(TextureFilter.Nearest, TextureFilter.Nearest, false);
		packer.dispose();
		hills = atlas.findRegion("hills");
		barrel = atlas.findRegion("barrel");
		up = atlas.findRegion("up");
		down = atlas.findRegion("down");
		
		textureRegionsMap = new HashMap<String, TextureRegion>();
		
		bullet_splash = atlas.findRegion("bullet_splash");
		hit = atlas.findRegion("hit");
		flash = atlas.findRegion("flash");
		textureRegionsMap.put("data/bullet_splash.png", bullet_splash);
		textureRegionsMap.put("data/hit.png", hit);
		textureRegionsMap.put("data/flash.png", flash);
		textureRegionsMap.put("data/btr.png", atlas.findRegion("btr"));

		items = loadTexture("data/items.png");
//		mainMenu = new TextureRegion(items, 0, 224, 300, 110);
		play= new TextureRegion(items, 92, 231, 114, 25);
		highScores = new TextureRegion(items, 4, 269, 290, 25);
		help = new TextureRegion(items, 92, 307, 114, 25);
		resume = new TextureRegion(items, 224, 172, 192, 48);
		quit = new TextureRegion(items, 224, 128, 192, 48);
		ready = new TextureRegion(items, BACKGROUND_HEIGHT, 224, 192, 32);
		gameOver = new TextureRegion(items, 352, 256, 160, 96);
		highScoresRegion = new TextureRegion(items, 0, 257, 300, 110 / 3);
		logo = new TextureRegion(items, 0, 352, 274, 142);
		soundOff = new TextureRegion(items, 0, 0, 64, 64);
		soundOn = new TextureRegion(items, 64, 0, 64, 64);
		arrow = new TextureRegion(items, 0, 64, 64, 64);
		pause = new TextureRegion(items, 64, 64, 64, 64);

		spring = new TextureRegion(items, 128, 0, 32, 32);
		castle = new TextureRegion(items, 128, 64, 64, 64);
		coinAnim = new Animation(0.2f, new TextureRegion(items, 128, 32, 32, 32), new TextureRegion(items, 160, 32, 32, 32),
			new TextureRegion(items, 192, 32, 32, 32), new TextureRegion(items, 160, 32, 32, 32));
		bobJump = new Animation(0.2f, new TextureRegion(items, 0, 128, 32, 32), new TextureRegion(items, 32, 128, 32, 32));
		bobFall = new Animation(0.2f, new TextureRegion(items, 64, 128, 32, 32), new TextureRegion(items, 96, 128, 32, 32));
		bobHit = new TextureRegion(items, 128, 128, 32, 32);
		squirrelFly = new Animation(0.2f, new TextureRegion(items, 0, 160, 32, 32), new TextureRegion(items, 32, 160, 32, 32));
		platform = new TextureRegion(items, 64, 160, 64, 16);
		brakingPlatform = new Animation(0.2f, new TextureRegion(items, 64, 160, 64, 16), new TextureRegion(items, 64, 176, 64, 16),
			new TextureRegion(items, 64, 192, 64, 16), new TextureRegion(items, 64, 208, 64, 16));

		font = new BitmapFont(Gdx.files.internal("data/font.fnt"), Gdx.files.internal("data/font.png"), false);

		music = Gdx.audio.newMusic(Gdx.files.internal("data/music.mp3"));
		music.setLooping(true);
		music.setVolume(0.5f);
		if (Settings.soundEnabled) music.play();
		jumpSound = Gdx.audio.newSound(Gdx.files.internal("data/jump.ogg"));
		highJumpSound = Gdx.audio.newSound(Gdx.files.internal("data/highjump.ogg"));
		hitSound = Gdx.audio.newSound(Gdx.files.internal("data/hit.ogg"));
		coinSound = Gdx.audio.newSound(Gdx.files.internal("data/coin.ogg"));
		clickSound = Gdx.audio.newSound(Gdx.files.internal("data/click.ogg"));
	}

	public static void playSound (Sound sound) {
		if (Settings.soundEnabled) sound.play(1);
	}
}
